package heima3_2.cn.osc.ui.view;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import net.oschina.app.R;

/**
 * @author U 自定义下拉刷新的ListView
 */
public class RefreshListView extends ListView {
	private View mHeadView;
	private float mDownY;
	private int mHeadViewHeight;
	private static final int PULL_REFRESH = 101;// 下拉刷新
	private static final int RELEASE_REFRESH = 102;// 释放刷新
	private static final int REFRESHING = 103;// 正在刷新
	private int mCurrentState = PULL_REFRESH;// 默认的情况是下拉刷新
	private ImageView mIvArrow;
	private TextView mTvState;
	private TextView mTvDate;
	private ProgressBar mPb;
	private int mPaddingTop;
	private boolean isLoadingMore;
	// * 1 写个类继承ListView
	// * 2 下拉刷新
	// * 1 添加头部
	// * 2 隐藏头部
	// * 3 onTouchEvent
	// 1 down事件：获取按下去的点
	// 2 移动事件
	// 3 处理抬起事件
	// * 4 提供接口
	// * 5 细节Bug需要处理

	// * 3 底部加载更多
	// * 1 添加尾部
	// * 2 隐藏起来
	// * 3 setOnScrollListener
	// * 4 判断静止并且滑动底部
	// * 5 提供接口
	// * 6 细节Bug需要处理
	public RefreshListView(Context context) {
		this(context, null);
	}

	public RefreshListView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// 1 添加头部
		initHeadView();
		// 2 添加尾部
		initFootView();
		// 3 初始化事件
		initEvent();
	}

	// 添加头部
	private void initHeadView() {
		// 1 添加尾部 xml----View
		mHeadView = View.inflate(getContext(), R.layout.view_lv_head, null);
		// 2 添加头部
		addHeaderView(mHeadView);

		mIvArrow = (ImageView) mHeadView.findViewById(R.id.iv_arrow);
		mTvState = (TextView) mHeadView.findViewById(R.id.tv_refresh_state);
		mTvDate = (TextView) mHeadView.findViewById(R.id.tv_refresh_date);
		mPb = (ProgressBar) mHeadView.findViewById(R.id.pb);

		// 3 隐藏头部
		// 获取头部的高度
		// int headViewHeight = mHeadView.getHeight();// 0
		// 测量一下mHeadView
		// 获取测量高度和宽度
		mHeadView.measure(0, 0);// 0 看成占位
		mHeadViewHeight = mHeadView.getMeasuredHeight();
		Log.d("heima11", "" + mHeadViewHeight);
		mHeadView.setPadding(0, -mHeadViewHeight, 0, 0);

		mTvDate.setText(getCurrDate());
	}

	// 添加尾部
	private void initFootView() {
		// 1 xml --- View
		mFootView = View.inflate(getContext(), R.layout.view_lv_foot, null);
		addFooterView(mFootView);

		// 隐藏
		mFootView.setVisibility(View.GONE);
	}

	private void initEvent() {
		setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				// * 4 判断静止并且滑动底部
				// * 5 提供接口
				// * 6 细节Bug需要处理
				int lastVisiblePosition = getLastVisiblePosition();
				if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && (lastVisiblePosition == (getCount() - 1)) && !isLoadingMore) {
					isLoadingMore=true;
					mFootView.setVisibility(View.VISIBLE);
					// 提供接口
					if(onRefreshListener!=null){
						onRefreshListener.onLoadMore(RefreshListView.this);
					}
				}
			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

			}
		});
	}

	// 获取当前时间
	private String getCurrDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date();
		return sdf.format(d);
	}

	// 3 onTouchEvent
	// 1 down事件：
	// 获取按下去的点:获取Y
	// 2 移动事件
	// * 1 向下拉 和 当第一可见项等于0 （才有必要自己处理移动事件return true，其他交给ListView自己处理return
	// super.onTouchEvent(ev)）
	// * 2 状态的分析：下拉刷新，释放刷新，正在刷新，默认情况，是下拉刷新
	// * 3 paddingTop=-headViewHeight+滑动的距离
	// * 4 mHeadView.setPadding(0, paddingTop, 0, 0); 有没有必要调用invalidate
	// * 5 假如paddingTop大于0并且currentState是下拉刷新
	// * 1 更新currentState释放刷新
	// * 2 更新UI和动画
	// * 6 假如paddingTop小于0并且currentState是释放刷新
	// * 1 更新currentState下拉刷新
	// * 2 更新UI和动画
	// * 7 抬起事件的处理
	// * 8 paddingTop大于0
	// *1 更新currentState正在刷新
	// mHeadView.setPadding(0, 0, 0, 0)
	// *2 更新UI和动画
	// * 9 paddingTop小于0
	// *1 更新currentState下拉刷新
	// *2 mHeadView.setPadding(0, -headViewHeight, 0, 0)
	// 3 处理抬起事件
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		int action = ev.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			// 获取按下去的点:获取Y
			mDownY = ev.getY();
			// 点，弹出刷拉刷新的问题
			mPaddingTop=0;
			break;
		case MotionEvent.ACTION_MOVE:
			float moveY = ev.getY();
			int dy = (int) (moveY - mDownY + 0.5f);
			// paddingTop

			mPaddingTop = -mHeadViewHeight + dy;

			// 向下拉 和 当第一可见项等于0 （才有必要自己处理移动事件return true，其他交给ListView自己处理return
			// super.onTouchEvent(ev)）
			if (dy > 0 && getFirstVisiblePosition() == 0) {// 自己处理移动的事件
				// 假如paddingTop大于0并且currentState是下拉刷新
				//// * 1 更新currentState释放刷新
				//// * 2 更新UI和动画
				if (mPaddingTop > 0 && mCurrentState == PULL_REFRESH) {
					// 更新currentState释放刷新
					mCurrentState = RELEASE_REFRESH;
					// 更新UI和动画
					changeUI();
				}
				// * 6 假如paddingTop小于0并且currentState是释放刷新
				// * 1 更新currentState下拉刷新
				// * 2 更新UI和动画
				if (mPaddingTop < 0 && mCurrentState == RELEASE_REFRESH) {
					// * 1 更新currentState下拉刷新
					mCurrentState = PULL_REFRESH;
					// * 2 更新UI和动画
					changeUI();
				}
				mHeadView.setPadding(0, mPaddingTop, 0, 0);
				invalidate();
				return true;
			}

			break;
		case MotionEvent.ACTION_UP:
			if (mPaddingTop > 0) {// 正在刷新
				// * 8 paddingTop大于0
				// *1 更新currentState正在刷新
				mCurrentState = REFRESHING;
				// *2 更新UI和动画
				mHeadView.setPadding(0, 0, 0, 0);
				changeUI();
				// 通知外面
				if (onRefreshListener != null) {
					onRefreshListener.onPullDown(this);
				}
			} else {
				// * 9 paddingTop小于0
				// *1 更新currentState下拉刷新
				mCurrentState = PULL_REFRESH;
				// *2 mHeadView.setPadding(0, -headViewHeight, 0, 0)
				mHeadView.setPadding(0, -mHeadViewHeight, 0, 0);
			}
			break;

		default:
			break;
		}
		return super.onTouchEvent(ev);
	}

	private void changeUI() {
		// 清理箭头的动画，以便gone
		mIvArrow.clearAnimation();
		switch (mCurrentState) {
		case PULL_REFRESH:
			mTvState.setText("下拉刷新");
			mIvArrow.setVisibility(View.VISIBLE);
			mPb.setVisibility(View.GONE);
			arrowDownAnim();
			break;
		case RELEASE_REFRESH:
			mTvState.setText("释放刷新...");
			mIvArrow.setVisibility(View.VISIBLE);
			mPb.setVisibility(View.GONE);
			arrowUpAnim();
			break;
		case REFRESHING:
			mTvState.setText("正在刷新...");
			mIvArrow.setVisibility(View.GONE);
			mPb.setVisibility(View.VISIBLE);
			mTvDate.setText(getCurrDate());
			break;

		default:
			break;
		}
	}

	// 箭头向上的动画
	public void arrowUpAnim() {
		RotateAnimation ra = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		ra.setDuration(300);
		ra.setFillAfter(true);
		mIvArrow.startAnimation(ra);
	}

	// 箭头向下的动画
	public void arrowDownAnim() {
		RotateAnimation ra = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
				RotateAnimation.RELATIVE_TO_SELF, 0.5f);
		ra.setDuration(300);
		ra.setFillAfter(true);
		mIvArrow.startAnimation(ra);
	}

	// 刷新完成的方法:提供给外界调用
	public void onRefreshCompleted() {
		// 1 隐藏进度条
		mPb.setVisibility(View.GONE);
		// 2 显示箭头
		mIvArrow.setVisibility(View.VISIBLE);
		// 3 设置当前的状态为下拉刷新的状态
		mCurrentState = PULL_REFRESH;
		// 4 头部隐藏
		mHeadView.setPadding(0, -mHeadViewHeight, 0, 0);
		// 5 底部加载完
		isLoadingMore=false;
		// 6 隐藏底部
		mFootView.setVisibility(View.GONE);
	}

	// 回调接口
	public interface OnRefreshListener {
		void onPullDown(RefreshListView view);
		void onLoadMore(RefreshListView view);
	}

	private OnRefreshListener onRefreshListener;
	private View mFootView;

	public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
		this.onRefreshListener = onRefreshListener;
	}
}
